package com.sqx.modules.task.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.UserCertificationDao;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserCertification;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserCertificationService;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.bidding.dao.HelpBiddingDao;
import com.sqx.modules.bidding.entity.HelpBidding;
import com.sqx.modules.bidding.service.HelpBiddingService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.fixedClassify.entity.FixedClassify;
import com.sqx.modules.fixedClassify.service.FixedClassifyService;
import com.sqx.modules.message.entity.MessageInfo;
import com.sqx.modules.message.service.MessageService;
import com.sqx.modules.pay.controller.app.AliPayController;
import com.sqx.modules.pay.service.WxService;
import com.sqx.modules.repairRecord.entity.RepairRecord;
import com.sqx.modules.repairRecord.service.RepairRecordService;
import com.sqx.modules.task.dao.HelpOrderDao;
import com.sqx.modules.task.dao.HelpTakeDao;
import com.sqx.modules.task.entity.HelpOrder;
import com.sqx.modules.task.entity.HelpTake;
import com.sqx.modules.task.service.HelpOrderService;
import com.sqx.modules.task.service.HelpTakeService;
import com.sqx.modules.utils.AmountCalUtils;
import com.sqx.modules.utils.LonLatUtil;
import com.sqx.modules.utils.SenInfoCheckUtil;
import org.apache.commons.lang.StringUtils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 跑腿订单
 */
@Service
public class HelpOrderServiceImpl extends ServiceImpl<HelpOrderDao, HelpOrder> implements HelpOrderService {

    /**
     * 跑腿订单
     */
    @Autowired
    private HelpOrderDao helpOrderDao;
    @Autowired
    private FixedClassifyService fixedClassifyService;
    /**
     * 用户金额
     */
    @Autowired
    private UserMoneyService userMoneyService;
    @Autowired
    private HelpBiddingService biddingService;

    @Resource
    private HelpBiddingDao biddingDao;
    /**
     * 用户金额明细
     */
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private UserService userService;

    @Resource
    private UserDao userDao;

    @Autowired
    private HelpTakeService helpTakeService;
    @Autowired
    private FixedClassifyService classifyService;

    @Autowired
    private MessageService messageService;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private RepairRecordService repairRecordService;

    @Autowired
    private WxService wxService;
    @Autowired
    private AliPayController aliPayController;
    @Autowired
    private HelpTakeDao takeDao;
    @Autowired
    private UserCertificationService userCertificationService;

    @Resource
    private UserCertificationDao userCertificationDao;


    @Override
    public Result selectHelpOrder(int page, int limit) {
        return Result.success().put("data", helpOrderDao.selectList(new QueryWrapper<>()));
    }

    @Override
    public Result selectCreateHelpOrder(int page, int limit, Integer status, Long userId, Long gameId) {
        Page<HelpOrder> pages = new Page<>(page, limit);
        IPage<HelpOrder> helpOrderIPage = helpOrderDao.selectCreateHelpOrder(pages, status, userId, gameId);
        List<HelpOrder> records = helpOrderIPage.getRecords();
        for (HelpOrder helpOrder : records) {
            if (helpOrder.getFixedClassifyId() != null) {
                FixedClassify classify = fixedClassifyService.getById(helpOrder.getFixedClassifyId());
                helpOrder.setFixedClassifyName(classify.getClassifyName());
                helpOrder.setFixedClassImg(classify.getImg());
            }
            if (helpOrder.getHelpTakeId() != null) {
                HelpTake helpTake = helpTakeService.selectHelpTakeById(helpOrder.getHelpTakeId());
                helpOrder.setHelpTake(helpTake);
            }
            UserEntity userEntity = userService.selectUserById(helpOrder.getUserId());
            helpOrder.setUser(userEntity);
        }
        return Result.success().put("data", new PageUtils(helpOrderIPage));
    }

    @Override
    public Result selectStatusHelpOrder(int page, int limit, String phone, String content, Integer status, Long gameId, Integer taskType) {
        phone = phone.trim();
        Page<HelpOrder> pages = new Page<>(page, limit);
        IPage<HelpOrder> helpOrderIPage = helpOrderDao.selectStatusHelpOrder(pages, phone, content, status, gameId, taskType);
        List<HelpOrder> records = helpOrderIPage.getRecords();
        for (HelpOrder helpOrder : records) {
            if (helpOrder.getHelpTakeId() != null) {
                HelpTake helpTake = helpTakeService.selectHelpTakeById(helpOrder.getHelpTakeId());
                helpOrder.setHelpTake(helpTake);
            }
            UserEntity userEntity = userService.selectUserById(helpOrder.getUserId());
            helpOrder.setUser(userEntity);
            if (helpOrder.getHelpTake() == null) {
                helpOrder.setCommission(BigDecimal.ZERO);
            } else {
                if (helpOrder.getStatus() != 4 && helpOrder.getStatus() != 5) {
                    UserEntity helpTakeUser = userService.selectUserById(helpOrder.getHelpTake().getUserId());
                    if (helpTakeUser != null) {
                        BigDecimal money = helpOrder.getMoney();
                        if (helpOrder.getPaySumMoney() != null) {
                            money = helpOrder.getPaySumMoney();
                        }
                        BigDecimal commission = money.multiply(helpTakeUser.getRate()).setScale(2, BigDecimal.ROUND_DOWN);
                        helpOrder.setCommission(commission);
                    } else {
                        helpOrder.setCommission(BigDecimal.ZERO);
                    }
                }
                if (helpOrder.getStatus() == 5) {
                    helpOrder.setCommission(BigDecimal.ZERO);
                }
            }
        }
        return Result.success().put("data", new PageUtils(helpOrderIPage));
    }


    @Override
    public Integer countHelpOrderByCreateTime(String time, Integer flag) {
        return helpOrderDao.countHelpOrderByCreateTime(time, flag);
    }


    @Override
    public Double sumPrice(String time, Integer flag) {
        return helpOrderDao.sumPrice(time, flag);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result choiceBidding(Long orderId, Long biddingId) {
        HelpBidding bidding = biddingService.getById(biddingId);
        HelpOrder helpOrder = helpOrderDao.selectById(orderId);
        if (helpOrder.getStatus() == 3) {
            return Result.error("当前订单已被支付");
        }
        //用户付款
        UserEntity userEntity = userService.getById(helpOrder.getUserId());
        UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(userEntity.getUserId());
        if (userMoney.getMoney().compareTo(bidding.getOfferMoney()) >= 0) {
            userMoneyService.updateMoney(2, userEntity.getUserId(), bidding.getOfferMoney());
            helpOrder.setPayWay(1);
            choseUserOrder(bidding, helpOrder);
            return Result.success();

        } else {
            return Result.error("余额不足,请充值后操作");

        }
    }

    @Override
    public Result updateTimeAndRemarks(Long helpOrderId, String deliveryTime, String remarks) {
        HelpOrder helpOrder = helpOrderDao.selectById(helpOrderId);
        helpOrder.setDeliveryTime(deliveryTime);
        helpOrder.setRemarks(remarks);
        return Result.upStatus(helpOrderDao.updateById(helpOrder));

    }

    @Override
    public IPage<HelpOrder> selectNowDayOrders(Integer page, Integer limit, Long userId) {
        Page<HelpOrder> pages;
        if (page != null && limit != null) {
            pages = new Page<>(page, limit);
        } else {
            pages = new Page<>();
            pages.setSize(-1);
        }
        return helpOrderDao.selectNowDayOrders(pages, userId);

    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void choseUserOrder(HelpBidding bidding, HelpOrder helpOrder) {
        //用户选择的报价人
        UserEntity choseUserEntity = userService.getById(bidding.getUserId());
        //发布万能任务的用户
        UserEntity userEntity = userService.getById(helpOrder.getUserId());
        helpOrder.setWinningUserId(bidding.getUserId());
        CommonInfo one = commonInfoService.findOne(120);
        String value = one.getValue();
        helpOrder.setMoney(bidding.getOfferMoney());
        BigDecimal commission = bidding.getOfferMoney().subtract(bidding.getOfferMoney().multiply(new BigDecimal(value)));
        helpOrder.setCommission(commission);
        int code = (int) ((Math.random() * 9 + 1) * 1000);
        helpOrder.setCode(String.valueOf(code));
        helpOrderDao.updateById(helpOrder);
        //修改被选中的人为已雇佣
        bidding.setStatus(1);
        biddingService.updateById(bidding);
        //修改其他报价的人的状态
        HelpBidding helpBidding = new HelpBidding();
        helpBidding.setStatus(2);
        biddingService.update(helpBidding, new QueryWrapper<HelpBidding>().eq("helper_id", helpOrder.getId()).ne("user_id", bidding.getUserId()));
        HelpTake helpTake = new HelpTake();
        helpTake.setStatus(1);
        helpTake.setUserId(bidding.getUserId());
        helpTake.setMoney(helpOrder.getCommission());
        helpTake.setOrderId(helpOrder.getId());
        helpTake.setCreateTime(new Date());
        takeDao.insertHelpTake(helpTake);
        helpOrder.setHelpTakeId(helpTake.getId());
        helpOrder.setStatus(2);
        helpOrder.setIsPay(1);
        helpOrderDao.updateById(helpOrder);
        //用户消息通知
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setContent("你的万能任务已被您分配给用户《" + choseUserEntity.getUserName() + "》");
        messageInfo.setTitle("万能任务选择结果通知！");
        messageInfo.setState(String.valueOf(4));
        messageInfo.setUserName(userEntity.getUserName());
        messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
        messageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        messageService.saveBody(messageInfo);

        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(helpOrder.getUserId());
        userMoneyDetails.setTitle("万能任务：" + helpOrder.getContent());
        userMoneyDetails.setContent("任务扣款：" + helpOrder.getMoney());
        userMoneyDetails.setType(2);
        userMoneyDetails.setMoney(helpOrder.getMoney());
        userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);
        //获得派送资格的师傅的消息通知
        UserEntity offerUser = userService.getById(bidding.getUserId());


        FixedClassify fixedClassify = classifyService.getById(helpOrder.getFixedClassifyId());

        if (bidding.getUserType() == null || bidding.getUserType() == 3) {
            if (StringUtils.isNotBlank(offerUser.getMasterOpenId())) {
                String offUser = commonInfoService.findOne(313).getValue();
                List<String> msgList = new ArrayList<>();
                msgList.add(helpOrder.getOrderNo());
                msgList.add(fixedClassify.getClassifyName());
                msgList.add("已接单");
                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
                msgList.add("你的报价金额已被选中,点击查看详情");
                SenInfoCheckUtil.sendMasterMsg(offerUser.getMasterOpenId(), offUser, msgList, 4);
            }
            MessageInfo offerMessageInfo = new MessageInfo();
            offerMessageInfo.setContent("您参与报价的万能任务《" + helpOrder.getContent() + "》已派发给您,用户已付款,请尽快完成");
            offerMessageInfo.setTitle("报价结果通知！");
            offerMessageInfo.setState(String.valueOf(7));
            offerMessageInfo.setUserName(offerUser.getUserName());
            offerMessageInfo.setUserId(String.valueOf(offerUser.getUserId()));
            offerMessageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            messageService.saveBody(offerMessageInfo);
        } else {
            if (StringUtils.isNotBlank(offerUser.getShopOpenId())) {
                String offUser = commonInfoService.findOne(623).getValue();
                List<String> msgList = new ArrayList<>();
                msgList.add(helpOrder.getOrderNo());
                msgList.add(fixedClassify.getClassifyName());
                msgList.add("已接单");
                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
                msgList.add("你的报价金额已被选中,点击查看详情");
                SenInfoCheckUtil.sendShopMsg(offerUser.getShopOpenId(), offUser, null, msgList, 7);
            }
            MessageInfo offerMessageInfo = new MessageInfo();
            offerMessageInfo.setContent("您参与报价的万能任务《" + helpOrder.getContent() + "》已派发给您,用户已付款,请尽快完成");
            offerMessageInfo.setTitle("报价结果通知！");
            offerMessageInfo.setState(String.valueOf(8));
            offerMessageInfo.setUserName(offerUser.getUserName());
            offerMessageInfo.setUserId(String.valueOf(offerUser.getUserId()));
            offerMessageInfo.setCreateAt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            messageService.saveBody(offerMessageInfo);
        }
    }

    @Override
    public Result selectNewHelpOrderList(int page, int limit, Long gameId, String latitude, String longitude, Integer sort, Integer taskType, Long classifyId, Long userId) {
        Page<HelpOrder> pages = new Page<>(page, limit);
        IPage<HelpOrder> helpOrderIPage = helpOrderDao.selectNewHelpOrderList(pages, gameId, latitude, longitude, sort, taskType, classifyId, userId);
        return Result.success().put("data", new PageUtils(helpOrderIPage));
    }

    @Override
    public Result selectHelpOrderByClassifyList(int page, int limit, Long classifyId, Long gameId) {
        Page<HelpOrder> pages = new Page<>(page, limit);
        IPage<HelpOrder> helpOrderIPage = helpOrderDao.selectHelpOrderByClassifyList(pages, classifyId, gameId);
        return Result.success().put("data", new PageUtils(helpOrderIPage));
    }

    @Override
    public Result updateHelpOrderByStatus(String ids, Integer status, String content) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (String id : ids.split(",")) {
            HelpOrder helpOrder = helpOrderDao.selectById(Long.parseLong(id));
            if (helpOrder != null && helpOrder.getStatus() == 1) {
                UserEntity userEntity = userService.selectUserById(helpOrder.getUserId());
                if (status == 1) {
                    helpOrder.setStatus(2);
                    helpOrderDao.updateById(helpOrder);
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setContent("您好，您的万能任务申请已经通过了！");
                    messageInfo.setTitle("万能任务结果通知！");
                    messageInfo.setState(String.valueOf(5));
                    messageInfo.setUserName(userEntity.getUserName());
                    messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                    messageInfo.setCreateAt(sdf.format(new Date()));
                    messageService.saveBody(messageInfo);
                } else {
                    helpOrder.setStatus(5);
                    helpOrder.setCause(content);
                    helpOrderDao.updateById(helpOrder);
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setContent("您好，您的万能任务申请被拒绝了！原因：" + content);
                    messageInfo.setTitle("万能任务结果通知！");
                    messageInfo.setState(String.valueOf(5));
                    messageInfo.setUserName(userEntity.getUserName());
                    messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                    messageInfo.setCreateAt(sdf.format(new Date()));
                    messageService.saveBody(messageInfo);
                    userMoneyService.updateMoney(1, helpOrder.getUserId(), helpOrder.getMoney());
                    UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
                    userMoneyDetails.setUserId(helpOrder.getUserId());
                    userMoneyDetails.setTitle("[万能任务退款]：" + helpOrder.getContent());
                    userMoneyDetails.setContent("万能任务退款：" + helpOrder.getMoney());
                    userMoneyDetails.setType(1);
                    userMoneyDetails.setMoney(helpOrder.getMoney());
                    userMoneyDetails.setCreateTime(sdf.format(new Date()));
                    userMoneyDetailsService.save(userMoneyDetails);
                }
            }
        }
        return Result.success();
    }

    @Override
    public Result selectHelpOrderByContentList(int page, int limit, String content, Long gameId) {
        Page<HelpOrder> pages = new Page<>(page, limit);
        IPage<HelpOrder> helpOrderIPage = helpOrderDao.selectHelpOrderByContentList(pages, content, gameId);
        return Result.success().put("data", new PageUtils(helpOrderIPage));
    }


    @Override
    public Result adminSaveBody(HelpOrder helpOrder) {
        FixedClassify classify = classifyService.getById(helpOrder.getFixedClassifyId());
        if (classify != null) {
            if (helpOrder.getTaskType() == 1) {
                if (helpOrder.getCommission().compareTo(classify.getMinOfferMoney()) < 0) {
                    return Result.error("悬赏最低价不能低于" + classify.getMinOfferMoney() + "元");
                }
            } else if (helpOrder.getTaskType() == 3) {
                helpOrder.setCommission(classify.getMoney());
            } else if (helpOrder.getTaskType() == 2) {
                if (helpOrder.getCommission().compareTo(classify.getMinQuoteMoney()) < 0) {
                    return Result.error("报价期望价格最低价不能低于" + classify.getMinQuoteMoney() + "元");
                }
            }
        } else {
            return Result.error("分类id不存在");
        }
        if (helpOrder.getTaskType() == 4) {
            UserCertification userCertification = userCertificationService.getOne(new QueryWrapper<UserCertification>().eq("user_id", helpOrder.getMasterUserId()));
            if (userCertification.getOnLine() == null || userCertification.getOnLine() == 2) {
                return Result.error("当前师傅未上线，请更换其他师傅吧！");
            }
            //判断用户地址和师傅地址是否在一个城市
            if (!helpOrder.getCity().equals(userCertification.getCity())) {
                return Result.error("师傅距离您太远了，请换个师傅吧！");
            }
        }


        helpOrder.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        helpOrder.setOrderNo(getGeneralOrder());
        helpOrder.setMoney(helpOrder.getCommission());


        UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(helpOrder.getUserId());
        if (userMoney.getMoney().doubleValue() < helpOrder.getCommission().doubleValue()) {
            return Result.error("钱包余额不足");
        }


        //报价
        if (helpOrder.getTaskType() == 2) {
            if (helpOrder.getCommission().doubleValue() <= 0) {
                return Result.error("金额必须大于0");
            }
            helpOrder.setStatus(1);
        } else {
            helpOrder.setStatus(0);
        }
        helpOrderDao.insert(helpOrder);

        CommonInfo one = commonInfoService.findOne(120);
        String value = one.getValue();
        Double mul = AmountCalUtils.mul(helpOrder.getCommission().doubleValue(), Double.parseDouble(value));
        BigDecimal sub = AmountCalUtils.sub(helpOrder.getMoney(), BigDecimal.valueOf(mul));
        userMoneyService.updateMoney(2, helpOrder.getUserId(), helpOrder.getMoney());
        helpOrder.setCommission(sub);
        helpOrder.setPayWay(1);
        helpOrder.setStatus(1);
        helpOrder.setIsPay(1);
        helpOrderDao.updateById(helpOrder);
        if (helpOrder.getTaskType() == 4) {
            HelpTake helpTake = new HelpTake();
            helpTake.setOrderId(helpOrder.getId());
            helpTake.setUserId(helpOrder.getMasterUserId());
            Result result = helpTakeService.saveBody(helpTake);
            if (!"0".equals(String.valueOf(result.get("code")))) {
                return result;
            }
        }
        return walletPayMoney(helpOrder);
    }

    @Override
    public Result saveBody(HelpOrder helpOrder) {
        FixedClassify classify = classifyService.getById(helpOrder.getFixedClassifyId());
        if (classify != null) {
            if (helpOrder.getTaskType() == 1) {
                if (helpOrder.getCommission().compareTo(classify.getMinOfferMoney()) < 0) {
                    return Result.error("悬赏最低价不能低于" + classify.getMinOfferMoney() + "元");
                }
            } else if (helpOrder.getTaskType() == 3) {
                helpOrder.setCommission(classify.getMoney());
            } else if (helpOrder.getTaskType() == 2) {
                if (helpOrder.getCommission().compareTo(classify.getMinQuoteMoney()) < 0) {
                    return Result.error("报价期望价格最低价不能低于" + classify.getMinQuoteMoney() + "元");
                }
            }
        } else {
            return Result.error("分类id不存在");
        }
        if (helpOrder.getTaskType() == 4) {
            UserCertification userCertification = userCertificationService.getOne(new QueryWrapper<UserCertification>().eq("user_id", helpOrder.getMasterUserId()));
            if (userCertification.getOnLine() == null || userCertification.getOnLine() == 2) {
                return Result.error("当前师傅未上线，请更换其他师傅吧！");
            }
            //判断用户地址和师傅地址是否在一个城市
            if (!helpOrder.getCity().equals(userCertification.getCity())) {
                return Result.error("师傅距离您太远了，请换个师傅吧！");
            }
        }


        helpOrder.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        helpOrder.setOrderNo(getGeneralOrder());
        helpOrder.setMoney(helpOrder.getCommission());
        //报价
        if (helpOrder.getTaskType() == 2) {
            if (helpOrder.getCommission().doubleValue() <= 0) {
                return Result.error("金额必须大于0");
            }
            helpOrder.setStatus(1);
        } else {
            helpOrder.setStatus(0);
        }
        helpOrderDao.insert(helpOrder);
        return Result.success().put("data", helpOrder);
    }

    /*
     * 零钱支付
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result payMoney(Long ordersId) {
        HelpOrder helpOrder = helpOrderDao.selectById(ordersId);
        if (helpOrder.getStatus() == 0) {
            UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(helpOrder.getUserId());
            if (userMoney.getMoney().doubleValue() >= helpOrder.getCommission().doubleValue()) {
                CommonInfo one = commonInfoService.findOne(120);
                String value = one.getValue();
                Double mul = AmountCalUtils.mul(helpOrder.getCommission().doubleValue(), Double.parseDouble(value));
                BigDecimal sub = AmountCalUtils.sub(helpOrder.getMoney(), BigDecimal.valueOf(mul));
                userMoneyService.updateMoney(2, helpOrder.getUserId(), helpOrder.getMoney());
                helpOrder.setCommission(sub);
                helpOrder.setPayWay(1);
                helpOrder.setStatus(1);
                helpOrder.setIsPay(1);
                helpOrderDao.updateById(helpOrder);
                if (helpOrder.getTaskType() == 4) {
                    HelpTake helpTake = new HelpTake();
                    helpTake.setOrderId(helpOrder.getId());
                    helpTake.setUserId(helpOrder.getMasterUserId());
                    Result result = helpTakeService.saveBody(helpTake);
                    if (!"0".equals(String.valueOf(result.get("code")))) {
                        return result;
                    }
                }

                // 新建线程池来处理消息推送
                ExecutorService exec = Executors.newFixedThreadPool(5);

                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        // 向附近的商家和师傅推送这个订单
                        // 1.获取这个订单的经纬度
                        String latitude = helpOrder.getLatitude();//纬度
                        String longitude = helpOrder.getLongitude();//经度
                        // 2.获取到系统配置的推送范围
                        Integer pushRange = Integer.parseInt(commonInfoService.findOne(628).getValue());
                        // 3.获取到所有的师傅和商家
                        List<UserEntity> masterAndShop = userDao.getMasterAndShop();
                        // 4.过滤掉距离大于推送范围的师傅和商家
                        List<UserEntity> filterList = masterAndShop.stream().filter(item -> {
                            GlobalCoordinates target = new GlobalCoordinates(Double.parseDouble(latitude), Double.parseDouble(longitude));
                            GlobalCoordinates source = new GlobalCoordinates(Double.parseDouble(item.getLatitude()), Double.parseDouble(item.getLongitude()));
                            Integer distance = (int) LonLatUtil.getDistanceMeter(target, source, Ellipsoid.Sphere);//计算两个经纬度之间的距离
                            return distance <= pushRange * 1000;
                        }).collect(Collectors.toList());
                        // 5.向师傅和商家推送站内消息、微信服务消息、App消息
                        for (UserEntity userEntity : filterList) {
                            // 5.1 先判断是师傅还是商家
                            if (userEntity.getUserType() == 3 && (userEntity.getIsAuthentication() == 1 || userEntity.getIsAuthentication() == 3)) {
                                // 5.2 向师傅推送站内消息、微信服务消息、App消息
                                // 5.2.1 推送站内消息
                                MessageInfo messageInfo = new MessageInfo();
                                messageInfo.setTitle("订单提醒");
                                messageInfo.setState(String.valueOf(7));
                                messageInfo.setContent("有用户下单了,请及时接单");
                                messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                                messageInfo.setUserName(userEntity.getUserName());
                                messageInfo.setIsSee("0");
                                messageService.saveBody(messageInfo);

                                // 5.2.2 推送微信服务消息
                                List<String> msgList = new ArrayList<>();
                                String masterValue = commonInfoService.findOne(630).getValue(); // 模板id
                                msgList.add(helpOrder.getOrderNo());
                                msgList.add(fixedClassifyService.getById(helpOrder.getFixedClassifyId()).getClassifyName());
                                msgList.add("1");
                                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
                                msgList.add(userService.getById(helpOrder.getUserId()).getUserName());
                                SenInfoCheckUtil.sendMasterMsg(userEntity.getMasterOpenId(), masterValue, msgList, 1);

                            }
                            if (userEntity.getUserType() == 2 && userEntity.getIsAuthentication() == 2) {
                                // 5.3 向商家推送站内消息、微信服务消息、App消息
                                // 5.3.1 推送站内消息
                                MessageInfo messageInfo = new MessageInfo();
                                messageInfo.setTitle("订单提醒");
                                messageInfo.setState(String.valueOf(8));
                                messageInfo.setContent("有用户下单了,请及时接单");
                                messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
                                messageInfo.setUserName(userEntity.getUserName());
                                messageInfo.setIsSee("0");
                                messageService.saveBody(messageInfo);

                                // 5.3.2 推送微信服务消息
                                List<String> msgList = new ArrayList<>();
                                String masterValue = commonInfoService.findOne(235).getValue(); // 模板id
                                msgList.add(helpOrder.getOrderNo());
                                msgList.add(fixedClassifyService.getById(helpOrder.getFixedClassifyId()).getClassifyName());
                                msgList.add("1");
                                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
                                msgList.add(userService.getById(helpOrder.getUserId()).getUserName());
                                SenInfoCheckUtil.sendShopMsg(userEntity.getShopOpenId(), masterValue, null, msgList, 1);
                            }
                        }
                    }
                };
                exec.execute(runnable);


                return walletPayMoney(helpOrder);
            } else {
                return Result.error("钱包余额不足");
            }
        } else {
            return Result.error("订单已支付");
        }
    }

    /**
     * 订单播报
     *
     * @return
     */
    @Override
    public Result orderBroadcast() {
        // 获取订单列表
        List<String> list = new ArrayList<>();
        this.lambdaQuery()
                .in(HelpOrder::getStatus, 2, 4)
                .orderByDesc(HelpOrder::getCreateTime)
                .last("limit 10").list()
                .forEach(it -> {
                    HelpTake one = helpTakeService.lambdaQuery()
                            .eq(HelpTake::getOrderId, it.getId())
                            .one();
                    UserEntity user = userService.getById(one.getUserId());
                    UserCertification userCertification = userCertificationService.lambdaQuery()
                            .eq(UserCertification::getUserId, user.getUserId()).one();
                    String str = "";
                    BigDecimal money = NumberUtil.round(NumberUtil.mul(it.getMoney(),user.getRate()), 2);
                    if(it.getStatus()==4){
                        if(userCertification.getClassify() == 1){
                            str = userCertification.getCity()+"市"+userCertification.getName()+"师傅完工验收，赚了"+money+"元";
                        }else {
                            str = userCertification.getName()+"完工验收，赚了"+money+"元";
                        }
                    } else if(it.getStatus() == 2 && it.getTaskType() == 2){
                        if(userCertification.getClassify() == 1){
                            str = userCertification.getCity()+"市"+userCertification.getName()+"师傅报价成功，"+userCertification.getName()+"报价的合理报价已成功选中";
                        }else {
                            str = userCertification.getName()+"报价成功，"+userCertification.getName()+"报价的合理报价已成功选中";
                        }
                    } else if(it.getStatus() == 2 && (it.getTaskType() == 1 || it.getTaskType() == 3)){
                        if(userCertification.getClassify() == 1){
                            str = userCertification.getCity()+"市"+userCertification.getName()+"师傅抢单成功";
                        }else {
                            str = userCertification.getName()+"抢单成功";
                        }
                    }
                    list.add(str);
                });
        return Result.success().put("data",list);
    }

    private Result walletPayMoney(HelpOrder helpOrder) {
        UserEntity userEntity = userService.getById(helpOrder.getUserId());
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(helpOrder.getUserId());
        userMoneyDetails.setTitle("万能任务");
        userMoneyDetails.setContent("万能任务扣款：" + helpOrder.getMoney());
        userMoneyDetails.setType(2);
        userMoneyDetails.setMoney(helpOrder.getMoney());
        userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);
        if (userEntity.getClientid() != null) {
            userService.pushToSingle("派发订单", "您的订单已经派发成功！", userEntity.getClientid());
        }
        String value = commonInfoService.findOne(312).getValue();
        FixedClassify fixedClassify = fixedClassifyService.getById(helpOrder.getFixedClassifyId());
        if (StringUtils.isNotBlank(userEntity.getOpenId())) {
            List<String> msgList = new ArrayList<>();
            msgList.add(helpOrder.getOrderNo());
            msgList.add(fixedClassify.getClassifyName());
            msgList.add("订单已付款");
            msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
            msgList.add("付款金额:" + helpOrder.getMoney());
            SenInfoCheckUtil.sendMsg(userEntity.getOpenId(), value, 1, msgList, 4);
        }
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setTitle("订单通知");
        messageInfo.setState(String.valueOf(11));
        messageInfo.setIsSee("0");
        messageService.saveBody(messageInfo);
        return Result.success();
    }


    @Override
    public Result saveBodys(HelpOrder helpOrder) {
        if (helpOrder.getCommission().doubleValue() <= 0) {
            return Result.error("金额必须大于0");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        helpOrder.setStatus(1);
        helpOrder.setCreateTime(date);
        helpOrder.setMoney(helpOrder.getCommission());
        helpOrderDao.insert(helpOrder);
        return Result.success();
    }


    @Override
    public Result updateHelpOrderById(HelpOrder helpOrder) {
        HelpOrder helpOrder1 = helpOrderDao.selectById(helpOrder.getId());
        if (!helpOrder1.getCommission().equals(helpOrder.getCommission())) {
            return Result.error("已发布任务不能修改金额！");
        }
        if (helpOrder1.getStatus() == 3 || helpOrder1.getStatus() == 4) {
            return Result.error("当前状态不允许修改！");
        }
        FixedClassify classify = classifyService.getById(helpOrder.getFixedClassifyId());
        if (classify != null) {
            if (helpOrder.getTaskType() == 1) {
                if (helpOrder.getCommission().compareTo(classify.getMinOfferMoney()) < 0) {
                    return Result.error("悬赏最低价不能低于" + classify.getMinOfferMoney() + "元");
                }
            } else if (helpOrder.getTaskType() == 3) {
                helpOrder.setCommission(classify.getMoney());
            } else if (helpOrder.getTaskType() == 2) {
                if (helpOrder.getCommission().compareTo(classify.getMinQuoteMoney()) < 0) {
                    return Result.error("报价期望价格最低价不能低于" + classify.getMinQuoteMoney() + "元");
                }
            }
        } else {
            return Result.error("分类id不存在");
        }
        //报价
        if (helpOrder.getTaskType() == 2) {
            if (helpOrder.getCommission().doubleValue() <= 0) {
                return Result.error("金额必须大于0");
            }
        }
        helpOrder.setMoney(helpOrder.getCommission());
        helpOrderDao.updateById(helpOrder);
        return Result.success();
    }

    @Override
    public Result updateHelpOrderByIds(HelpOrder helpOrder) {
        helpOrderDao.updateById(helpOrder);
        return Result.success();
    }

    @Override
    public Result deleteById(Long id) {
        HelpOrder helpOrder = helpOrderDao.selectById(id);
        if (helpOrder.getStatus() != 4 && helpOrder.getStatus() != 5) {
            return Result.error("当前状态不允许删除！");
        }
        helpOrderDao.deleteById(id);
        return Result.success();
    }

    @Override
    public Result deleteByIds(Long id) {
        HelpOrder helpOrder = helpOrderDao.selectById(id);
        if (helpOrder.getStatus() == 3 || helpOrder.getStatus() == 4) {
            helpOrderDao.deleteById(id);
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = sdf.format(new Date());
            if (helpOrder.getPayWay() == null || helpOrder.getPayWay() == 1) {
                userMoneyService.updateMoney(1, helpOrder.getUserId(), helpOrder.getMoney());
            } else if (helpOrder.getPayWay() == 2) {
                //微信
                boolean refund = wxService.refund(helpOrder.getOrderNo(), helpOrder.getMoney());
                if (!refund) {
                    return Result.error("退款失败，请联系客服处理！");
                }
            } else {
                //支付宝
                String data = aliPayController.alipayRefund(helpOrder.getOrderNo(), helpOrder.getMoney());
                if (StringUtils.isNotBlank(data)) {
                    log.error(data);
                    JSONObject jsonObject = JSON.parseObject(data);
                    JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                    String code1 = alipay_trade_refund_response.getString("code");
                    if (!"10000".equals(code1)) {
                        return Result.error("退款失败！" + alipay_trade_refund_response.getString("sub_msg"));
                    }
                } else {
                    return Result.error("退款失败！");
                }
            }

            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(helpOrder.getUserId());
            userMoneyDetails.setTitle("[万能任务退款]：" + helpOrder.getContent());
            userMoneyDetails.setContent("万能任务已原路退款：" + helpOrder.getMoney());
            userMoneyDetails.setType(1);
            userMoneyDetails.setMoney(helpOrder.getMoney());
            userMoneyDetails.setCreateTime(date);
            userMoneyDetailsService.save(userMoneyDetails);
            helpOrderDao.deleteById(id);
        }
        return Result.success();
    }

    @Override
    public Result outHelpOrder(Long id) {
        HelpOrder helpOrder = helpOrderDao.selectById(id);
        if (helpOrder.getStatus() != 0 && helpOrder.getStatus() != 1 && helpOrder.getStatus() != 2) {
            return Result.error("当前状态不允许取消！");
        }
        FixedClassify fixedClassify = fixedClassifyService.getById(helpOrder.getFixedClassifyId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        if (helpOrder.getIsPay() == 1) {
            if (helpOrder.getPayWay() == null || helpOrder.getPayWay() == 1) {
                userMoneyService.updateMoney(1, helpOrder.getUserId(), helpOrder.getMoney());
            } else if (helpOrder.getPayWay() == 2) {
                //微信
                boolean refund = wxService.refund(helpOrder.getOrderNo(), helpOrder.getMoney());
                if (!refund) {
                    return Result.error("退款失败，请联系客服处理！");
                }
            } else {
                //支付宝
                String data = aliPayController.alipayRefund(helpOrder.getOrderNo(), helpOrder.getMoney());
                if (StringUtils.isNotBlank(data)) {
                    log.error(data);
                    JSONObject jsonObject = JSON.parseObject(data);
                    JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                    String code1 = alipay_trade_refund_response.getString("code");
                    if (!"10000".equals(code1)) {
                        return Result.error("退款失败！" + alipay_trade_refund_response.getString("sub_msg"));
                    }
                } else {
                    return Result.error("退款失败！");
                }
            }
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(helpOrder.getUserId());
            userMoneyDetails.setTitle("[万能任务退款]：" + fixedClassify.getClassifyName());
            userMoneyDetails.setContent("万能任务已原路退款：" + helpOrder.getMoney());
            userMoneyDetails.setType(1);
            userMoneyDetails.setMoney(helpOrder.getMoney());
            userMoneyDetails.setCreateTime(date);
            userMoneyDetailsService.save(userMoneyDetails);
        }


        // 判断任务类型是否为报价订单 --> 2
        if (helpOrder.getTaskType() == 2) {
            // 先查询这个订单是否有人报价， 如果有人报价，绑定的订单状态改为雇佣失败
            List<HelpBidding> biddingList = biddingDao.selectList(new LambdaQueryWrapper<HelpBidding>().eq(HelpBidding::getHelperId, id));
            if (biddingList.size() > 0) {
                for (int i = 0; i < biddingList.size(); i++) {
                    HelpBidding helpBidding = biddingList.get(i);
                    helpBidding.setStatus(2);
                    biddingDao.updateById(helpBidding);

                    // 给报价人发送消息
                    // 判断是师傅还是商家
                    if (helpBidding.getUserType() == 2) {
                        // 商家
                        MessageInfo messageInfo = new MessageInfo();
                        messageInfo.setContent("您的报价订单" + helpOrder.getOrderNo() + "用户已取消");
                        messageInfo.setTitle("报价订单通知");
                        messageInfo.setUserName(userService.selectUserById(helpBidding.getUserId()).getUserName());
                        messageInfo.setUserId(String.valueOf(helpBidding.getUserId()));
                        messageInfo.setState(String.valueOf(6));
                        messageService.saveBody(messageInfo);
                    }

                    if (helpBidding.getUserType() == 3) {
                        // 师傅
                        MessageInfo messageInfo = new MessageInfo();
                        messageInfo.setContent("您的报价订单" + helpOrder.getOrderNo() + "用户已取消");
                        messageInfo.setTitle("报价订单通知");
                        messageInfo.setUserName(userService.selectUserById(helpBidding.getUserId()).getUserName());
                        messageInfo.setUserId(String.valueOf(helpBidding.getUserId()));
                        messageInfo.setState(String.valueOf(7));
                        messageService.saveBody(messageInfo);
                    }

                }
            }
        }

        helpOrder.setStatus(5);
        helpOrderDao.updateById(helpOrder);


        if (helpOrder.getHelpTakeId() != null) {
            HelpTake helpTake = helpTakeService.selectHelpTakeById(helpOrder.getHelpTakeId());
            helpTake.setStatus(4);
            helpTakeService.updateHelpTakeById(helpTake);
            UserEntity userEntity = userService.selectUserById(helpTake.getUserId());

            if (userEntity.getClientid() != null) {
                userService.pushToSingle("万能任务", "您的万能任务：" + fixedClassify.getClassifyName() + "，平台已经取消！", userEntity.getClientid());
            }
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setContent("您的万能任务：" + fixedClassify.getClassifyName() + "，平台已经取消！");
            messageInfo.setTitle("万能任务");
            messageInfo.setState(String.valueOf(5));
            messageInfo.setUserName(userEntity.getUserName());
            messageInfo.setUserId(String.valueOf(userEntity.getUserId()));
            messageService.saveBody(messageInfo);

            // 推送微信服务信息
            // 判断用户类型是 商家还是师傅
            if (StringUtils.isNotBlank(userEntity.getMasterOpenId())) {
                // 师傅的openid不为空
                String value = commonInfoService.findOne(313).getValue(); // 订单状态模版id
                List<String> msgList = new ArrayList<>();
                msgList.add(helpOrder.getOrderNo()); // 订单号
                msgList.add(fixedClassifyService.getById(helpOrder.getFixedClassifyId()).getClassifyName()); // 类型
                msgList.add("已取消");// 订单状态
                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)); // 操作时间
                msgList.add("您的订单已取消，点击查看详情");// 备注
                SenInfoCheckUtil.sendMasterMsg(userEntity.getMasterOpenId(), value, msgList, 4);
            }

            if (StringUtils.isNotBlank(userEntity.getShopOpenId())) {
                // 商家的openid不为空
                String value = commonInfoService.findOne(623).getValue(); // 订单状态模版id
                List<String> msgList = new ArrayList<>();
                msgList.add(helpOrder.getOrderNo()); // 订单编号
                msgList.add(fixedClassifyService.getById(helpOrder.getFixedClassifyId()).getClassifyName()); // 类型
                msgList.add("已取消");
                msgList.add(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)); // 时间
                msgList.add("您的订单已取消，点击查看详情");
                SenInfoCheckUtil.sendShopMsg(userEntity.getShopOpenId(), value, null, msgList, 7);
            }


        }


        return Result.success();
    }

    @Override
    public HelpOrder selectHelpOrderById(Long helpOrderId, Long userId, Long userIds, String longitude, String latitude) {
        HelpOrder helpOrder = helpOrderDao.selectById(helpOrderId);
        if (userIds != null) {
            UserEntity user = userService.getById(userIds);
            /*helpOrder.setRateMoney(user.getRate().multiply(helpOrder.getMoney()));
            if(helpOrder.getPaySumMoney()!=null){
                helpOrder.setSumRateMoney(user.getRate().multiply(helpOrder.getPaySumMoney()));
            }*/
            helpOrder.setRateMoney(helpOrder.getMoney());
            if (helpOrder.getPaySumMoney() != null) {
                helpOrder.setSumRateMoney(helpOrder.getPaySumMoney());
            }
        }
        List<RepairRecord> repairRecord = repairRecordService.list(new QueryWrapper<RepairRecord>().eq("order_type", 1).eq("order_no", helpOrder.getOrderNo()));
        if (repairRecord.size() > 0) {
            helpOrder.setIsRepair(1);
        } else {
            helpOrder.setIsRepair(0);
        }

        FixedClassify childrenClassify = classifyService.getById(helpOrder.getFixedClassifyId());
        FixedClassify parentClassify = classifyService.getById(childrenClassify.getParentId());
        helpOrder.setFixedClassifyName(parentClassify.getClassifyName() + "/" + childrenClassify.getClassifyName());
        helpOrder.setServiceName(childrenClassify.getClassifyName());
        helpOrder.setFixedClassImg(childrenClassify.getImg());
        UserEntity userEntity = userService.selectUserById(helpOrder.getUserId());
        helpOrder.setUser(userEntity);
        HelpTake helpTake = helpTakeService.selectHelpTakeById(helpOrder.getHelpTakeId());

        if (helpTake != null) {
            helpOrder.setHelpTake(helpTake);
        }
        // 判断任务类型是否为竞价任务 排除竞价失败的师傅
        if (helpOrder.getTaskType() != null && helpOrder.getTaskType() == 2) {
            if (helpOrder.getUserId().equals(userId)) {
                helpOrder.setBiddingList(biddingService.getOfferUserList(helpOrder.getId(), null));
            } else {
                List<HelpBidding> helpBiddingList = biddingService.getOfferUserList(helpOrder.getId(), userId);
                for (HelpBidding helpBidding : helpBiddingList) {
                    //如果有已雇佣的师傅，则其他师傅被排除掉
                    if (helpBidding.getStatus() == 1) {
                        helpBiddingList.removeIf(next -> next.getStatus() != 1);
                        break;
                    }
                }
                helpOrder.setBiddingList(helpBiddingList);
            }

        }

        if (userId != null) {
            // 根据用户id获取用户认证所在的经纬度
            UserCertification userCertification = userCertificationDao.selectOne(new LambdaQueryWrapper<UserCertification>().eq(UserCertification::getUserId, userId));

            // 根据经纬度计算订单距离用户认证所在地的距离
            GlobalCoordinates target = new GlobalCoordinates(Double.parseDouble(helpOrder.getLatitude()), Double.parseDouble(helpOrder.getLongitude()));
            GlobalCoordinates source = new GlobalCoordinates(Double.parseDouble(userCertification.getLatitude()), Double.parseDouble(userCertification.getLongitude()));
            Integer placeDistance = (int) LonLatUtil.getDistanceMeter(source, target, Ellipsoid.Sphere);
            helpOrder.setPlaceDistance(placeDistance.doubleValue());

        }


        if (StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude)) {
            GlobalCoordinates source = new GlobalCoordinates(Double.parseDouble(latitude), Double.parseDouble(longitude));
            GlobalCoordinates target = new GlobalCoordinates(Double.parseDouble(helpOrder.getLatitude()), Double.parseDouble(helpOrder.getLongitude()));
            Integer distances = (int) LonLatUtil.getDistanceMeter(source, target, Ellipsoid.Sphere);
            helpOrder.setDistance(distances.doubleValue());
        }
        return helpOrder;
    }


    private String getGeneralOrder() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return format + newString;
    }


}
